package top.zywork.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.zywork.common.DateParseUtils;
import top.zywork.common.RegexUtils;
import top.zywork.enums.DatePatternEnum;
import top.zywork.enums.GoodsOrderStatusEnum;
import top.zywork.enums.IncomeOutgoingTypeEnum;
import top.zywork.enums.PaymentTypeEnum;
import top.zywork.query.GoodsOrderQuery;
import top.zywork.query.PlatformAccountDetailQuery;
import top.zywork.service.AccountStatisticsService;
import top.zywork.vo.ResponseStatusVO;
import top.zywork.vo.StatisticsDayCountVO;
import top.zywork.vo.echarts.BasicLineChartVO;
import top.zywork.vo.echarts.MultipleLineChartVO;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 平台出入账统计控制器类<br/>
 *
 * 创建于2019-11-19<br/>
 *
 * @author http://zywork.top 王振宇
 * @version 1.0
 */
@RestController
@RequestMapping("/account-stat")
public class AccountStatisticsController extends BaseController {

    private AccountStatisticsService accountStatisticsService;

    /**
     * 统计平台总结余，总入账，总出账
     * @return
     */
    @PostMapping("account-count")
    public ResponseStatusVO countGoodsAndOrder() {
        BigDecimal total = accountStatisticsService.countAllAccount();
        BigDecimal totalIn = accountStatisticsService.countAllAccountByType(IncomeOutgoingTypeEnum.INCOME.getValue().byteValue());
        BigDecimal totalOut = accountStatisticsService.countAllAccountByType(IncomeOutgoingTypeEnum.OUTGOING.getValue().byteValue());
        BigDecimal totalCommission = accountStatisticsService.countTotalCommission();
        return ResponseStatusVO.ok("统计平台总结余，总入账，总出账", new Object[]{total, totalIn, totalOut, totalCommission});
    }

    /**
     * 指定时间周期内的总结余数
     * @param beginDateStr
     * @param endDateStr
     * @return
     */
    @PostMapping("all-account-by-date")
    public ResponseStatusVO countAllGoodsByTime(String beginDateStr, String endDateStr) {
        if (!RegexUtils.match(RegexUtils.REGEX_DATE, beginDateStr) || !RegexUtils.match(RegexUtils.REGEX_DATE, endDateStr)) {
            return ResponseStatusVO.dataError("时间字符串格式错误，正确的格式：yyyy-MM-dd", null);
        }
        Calendar beginCalendar = DateParseUtils.parseCalendar(beginDateStr, DatePatternEnum.DATE.getValue());
        Calendar endCalendar = DateParseUtils.parseCalendar(endDateStr, DatePatternEnum.DATE.getValue());
        BigDecimal total = accountStatisticsService.countAllAccountByTime(beginCalendar.getTime(), endCalendar.getTime());
        return ResponseStatusVO.ok(beginDateStr + "至" + endDateStr + "总结余数", total);
    }

    /**
     * 指定时间周期内的每日商品数（用于echarts统计）
     * @param beginDateStr
     * @param endDateStr
     * @return
     */
    @PostMapping("goods-count-by-date")
    public ResponseStatusVO countGoodsByTime(String beginDateStr, String endDateStr) {
        if (!RegexUtils.match(RegexUtils.REGEX_DATE, beginDateStr) || !RegexUtils.match(RegexUtils.REGEX_DATE, endDateStr)) {
            return ResponseStatusVO.dataError("时间字符串格式错误，正确的格式：yyyy-MM-dd", null);
        }
        Calendar beginCalendar = DateParseUtils.parseCalendar(beginDateStr, DatePatternEnum.DATE.getValue());
        Calendar endCalendar = DateParseUtils.parseCalendar(endDateStr, DatePatternEnum.DATE.getValue());
        List<StatisticsDayCountVO> statisticsDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),null);
        BasicLineChartVO basicLineChartVO = new BasicLineChartVO();
        List<String> xAxisData = new ArrayList<>();
        List<Number> seriesData = new ArrayList<>();
        for (StatisticsDayCountVO statisticsDayCountVO : statisticsDayCountVOList) {
            xAxisData.add(statisticsDayCountVO.getDateStr());
            seriesData.add(statisticsDayCountVO.getTotalDecimalCount());
        }
        basicLineChartVO.setxAxisData(xAxisData);
        basicLineChartVO.setSeriesData(seriesData);
        return ResponseStatusVO.ok(beginDateStr + "至" + endDateStr + "的每日结余数", basicLineChartVO);
    }

    /**
     * 获取指定周期内的平台流水统计（用于平台出入账 折线图echarts统计）
     * @param beginDateStr
     * @param endDateStr
     * @return
     */
    @PostMapping("running-water-by-date")
    public ResponseStatusVO getGoodsOrderStatusByTime(String beginDateStr, String endDateStr) {
        if (!RegexUtils.match(RegexUtils.REGEX_DATE, beginDateStr) || !RegexUtils.match(RegexUtils.REGEX_DATE, endDateStr)) {
            return ResponseStatusVO.dataError("时间字符串格式错误，正确的格式：yyyy-MM-dd", null);
        }
        Calendar beginCalendar = DateParseUtils.parseCalendar(beginDateStr, DatePatternEnum.DATE.getValue());
        Calendar endCalendar = DateParseUtils.parseCalendar(endDateStr, DatePatternEnum.DATE.getValue());
        //平台收入
        Byte type = 0;
        PlatformAccountDetailQuery platformAccountDetailQuery = PlatformAccountDetailQuery.builder().type(type).build();
        List<StatisticsDayCountVO> incomeDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        //平台支出
        type = 1;
        platformAccountDetailQuery.setType(type);
        List<StatisticsDayCountVO> spendingDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        //利润 （当日收入减去当日支出）
        List<StatisticsDayCountVO> profitsDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),null);
        MultipleLineChartVO multipleLineChartVO = new MultipleLineChartVO();
        List<String> xAxisData = new ArrayList<>();
        List<Number> incomeDataList = new ArrayList<>();
        List<Number> spendingDataList = new ArrayList<>();
        List<Number> profitsDataList = new ArrayList<>();
        BigDecimal incomeTotal = new BigDecimal(0);
        BigDecimal spendingTotal= new BigDecimal(0);
        BigDecimal profitsTotal = new BigDecimal(0);
        for (int i = 0; i < incomeDayCountVOList.size(); i++) {
            xAxisData.add(incomeDayCountVOList.get(i).getDateStr());
            //平台收入
            incomeDataList.add(incomeDayCountVOList.get(i).getTotalDecimalCount());
            incomeTotal = incomeTotal.add(incomeDayCountVOList.get(i).getTotalDecimalCount());
            //平台支出
            spendingDataList.add(spendingDayCountVOList.get(i).getTotalDecimalCount());
            spendingTotal = spendingTotal.add(spendingDayCountVOList.get(i).getTotalDecimalCount());
            //利润
            profitsDataList.add(profitsDayCountVOList.get(i).getTotalDecimalCount());
            profitsTotal = profitsTotal.add(profitsDayCountVOList.get(i).getTotalDecimalCount());
        }
        List<List<Number>> seriesDataArray = new ArrayList<>();
        seriesDataArray.add(incomeDataList);
        seriesDataArray.add(spendingDataList);
        seriesDataArray.add(profitsDataList);
        List<String> legend = new ArrayList<>();
        legend.add("平台收入");
        legend.add("平台支出");
        legend.add("利润");
        multipleLineChartVO.setLegend(legend);
        multipleLineChartVO.setxAxisData(xAxisData);
        multipleLineChartVO.setSeriesDataArray(seriesDataArray);
        return ResponseStatusVO.ok(beginDateStr + "至" + endDateStr + "的每日平台出入账统计", new Object[]{multipleLineChartVO,incomeTotal,spendingTotal,profitsTotal});
    }

    /**
     * 获取指定周期内的平台流水支付类型统计（用于 折线图echarts统计）
     * @param beginDateStr
     * @param endDateStr
     * @return
     */
    @PostMapping("pay-type-by-date")
    public ResponseStatusVO getAccountPayTypeByTime(String beginDateStr, String endDateStr) {
        if (!RegexUtils.match(RegexUtils.REGEX_DATE, beginDateStr) || !RegexUtils.match(RegexUtils.REGEX_DATE, endDateStr)) {
            return ResponseStatusVO.dataError("时间字符串格式错误，正确的格式：yyyy-MM-dd", null);
        }
        Calendar beginCalendar = DateParseUtils.parseCalendar(beginDateStr, DatePatternEnum.DATE.getValue());
        Calendar endCalendar = DateParseUtils.parseCalendar(endDateStr, DatePatternEnum.DATE.getValue());
        //微信收入
        byte incomeType = 0, spendingType = 1 ;
        PlatformAccountDetailQuery platformAccountDetailQuery = PlatformAccountDetailQuery.builder().payType(PaymentTypeEnum.WEIXIN_PAY.getValue().byteValue()).type(incomeType).build();
        List<StatisticsDayCountVO> weChat_IncomeDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        //微信支出
        platformAccountDetailQuery.setType(spendingType);
        List<StatisticsDayCountVO> weChat_SpendingDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        //支付宝收入
        platformAccountDetailQuery.setType(incomeType);
        platformAccountDetailQuery.setPayType(PaymentTypeEnum.ALIPAY.getValue().byteValue());
        List<StatisticsDayCountVO> aliPay_IncomeDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        //支付宝支出
        platformAccountDetailQuery.setType(spendingType);
        List<StatisticsDayCountVO> aliPay__SpendingDayCountVOList = accountStatisticsService.countDayAccountByTime(beginCalendar.getTime(), endCalendar.getTime(),platformAccountDetailQuery);
        MultipleLineChartVO multipleLineChartVO = new MultipleLineChartVO();
        List<String> xAxisData = new ArrayList<>();
        List<Number> wechat_IncomeDataList = new ArrayList<>();
        List<Number> wechat_SpendingDataList = new ArrayList<>();
        List<Number> aliPay_IncomeDataList = new ArrayList<>();
        List<Number> aliPay_SpendingDataList = new ArrayList<>();
        BigDecimal wechat_IncomeTotal = new BigDecimal(0);
        BigDecimal wechat_SpendingTotal= new BigDecimal(0);
        BigDecimal aliPay_IncomeTotal = new BigDecimal(0);
        BigDecimal aliPay_SpendingTotal = new BigDecimal(0);
        for (int i = 0; i < weChat_IncomeDayCountVOList.size(); i++) {
            xAxisData.add(weChat_IncomeDayCountVOList.get(i).getDateStr());
            //微信收入
            wechat_IncomeDataList.add(weChat_IncomeDayCountVOList.get(i).getTotalDecimalCount());
            wechat_IncomeTotal = wechat_IncomeTotal.add(weChat_IncomeDayCountVOList.get(i).getTotalDecimalCount());
            //微信支出
            wechat_SpendingDataList.add(weChat_SpendingDayCountVOList.get(i).getTotalDecimalCount());
            wechat_SpendingTotal = wechat_SpendingTotal.add(weChat_SpendingDayCountVOList.get(i).getTotalDecimalCount());
            //支付宝收入
            aliPay_IncomeDataList.add(aliPay_IncomeDayCountVOList.get(i).getTotalDecimalCount());
            aliPay_IncomeTotal = aliPay_IncomeTotal.add(aliPay_IncomeDayCountVOList.get(i).getTotalDecimalCount());
            //支付宝支出
            aliPay_SpendingDataList.add(aliPay__SpendingDayCountVOList.get(i).getTotalDecimalCount());
            aliPay_SpendingTotal = aliPay_SpendingTotal.add(aliPay__SpendingDayCountVOList.get(i).getTotalDecimalCount());
        }
        List<List<Number>> seriesDataArray = new ArrayList<>();
        seriesDataArray.add(wechat_IncomeDataList);
        seriesDataArray.add(wechat_SpendingDataList);
        seriesDataArray.add(aliPay_IncomeDataList);
        seriesDataArray.add(aliPay_SpendingDataList);
        List<String> legend = new ArrayList<>();
        legend.add("微信收入");
        legend.add("微信支出");
        legend.add("支付宝收入");
        legend.add("支付宝支出");
        multipleLineChartVO.setLegend(legend);
        multipleLineChartVO.setxAxisData(xAxisData);
        multipleLineChartVO.setSeriesDataArray(seriesDataArray);
        return ResponseStatusVO.ok(beginDateStr + "至" + endDateStr + "的每日平台出入账统计",
                new Object[]{multipleLineChartVO,wechat_IncomeTotal,wechat_SpendingTotal,aliPay_IncomeTotal,aliPay_SpendingTotal});
    }

    @Autowired
    public void setAccountStatisticsService(AccountStatisticsService accountStatisticsService) {
        this.accountStatisticsService = accountStatisticsService;
    }
}
